#include <stdbool.h>
#include <stdint.h>

#include "tgtdefs.h"
#include "nrfutils.h"

#include "matrix.h"
#include "keycode.h"
#include "layers.h"

layer_def_t* active_layer;

uint8_t fnl_key_states = 0;
uint8_t fnl_states = 0;

void set_active_layer(void)
{
	uint8_t row, col, fnm = 0, fnl = 0, locks_activated;
	
	layer_def_t* dflt_layer = &layers[0];
	
	// first check the modifier FN key states
	for (row = 0; row < NUM_ROWS; ++row)
	{
		for (col = 0; col < NUM_COLS; ++col)
		{
			if ((matrix[row] & _BV(col)) != 0)
			{
				uint8_t keycode = (*dflt_layer)[row][col];
				if (IS_FNM(keycode))
					fnm |= _BV(keycode - KC_FNM0);
				else if (IS_FNL(keycode))
					fnl |= _BV(keycode - KC_FNL0);
			}
		}
	}

	// at the moment we only support 3 modifier and 3 locking layers
	fnm &= 0b11;
	fnl &= 0b11;
	
	// do the locking layer change
	locks_activated = (fnl ^ fnl_key_states) & fnl;
	fnl_states ^= locks_activated;
	fnl_key_states = fnl;
	
	if (fnm)	// FN modifiers down?
		active_layer = &layers[fnm];
	else if (fnl_states)	// active locking layers?
		active_layer = &layers[fnl_states];
	else
		active_layer = dflt_layer;
}

uint8_t get_keycode(uint8_t row, uint8_t col)
{
	uint8_t ret_val = (*active_layer)[row][col];

	return ret_val;
}

bool is_pressed_keycode(uint8_t keycode)
{
	uint8_t row, col;
	
	for (row = 0; row < NUM_ROWS; ++row)
	{
		for (col = 0; col < NUM_COLS; ++col)
		{
			if ((*active_layer)[row][col] == keycode)
				return (matrix[row] & _BV(col)) != 0;
		}
	}
	
	return false;
}
